package com.vsu.bookstore.util;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class CurrencyExchangeProvider
{
  private final static String URL_BASE = "http://www.cbr.ru/scripts/XML_daily.asp";

  private final static String REQUEST_BASE = "date_req=";

  private final static String EURO_ID = "R01239";

  private static Document dom = null;

  private static Double euroToRubleRatio = -1d;

  private static double extractEuroValue()
  {
    final Element elem = dom.getDocumentElement();
    final NodeList courses = elem.getElementsByTagName("Valute");
    int idx = 1;
    do
    {
      final Element node = (Element) courses.item(idx++);
      if (node.getAttribute("ID").toString().equals(EURO_ID))
        return getDoubleValue(node, "Value");
    } while (idx < courses.getLength());
    return 0d;
  }

  private static void fetchDocument()
  {
    URLConnection urlConnection;
    DataInputStream inStream = null;
    DataOutputStream outStream;
    final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
    try
    {
      final URL url = new URL(URL_BASE);
      final String body =  REQUEST_BASE + format.format(new Date());

      urlConnection = url.openConnection();
      ((HttpURLConnection) urlConnection).setRequestMethod("GET");
      urlConnection.setDoInput(true);
      urlConnection.setDoOutput(true);
      urlConnection.setUseCaches(false);
      urlConnection.setRequestProperty("Content-Length", "" + body.length());

      outStream = new DataOutputStream(urlConnection.getOutputStream());
      inStream = new DataInputStream(urlConnection.getInputStream());

      outStream.writeBytes(body);
      outStream.flush();
      outStream.close();

      final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      final DocumentBuilder db = dbf.newDocumentBuilder();
      dom = db.parse(inStream);
      inStream.close();
    } catch (final ParserConfigurationException pce)
    {
      pce.printStackTrace();
    } catch (final SAXException se)
    {
      se.printStackTrace();
    } catch (final IOException ioe)
    {
      ioe.printStackTrace();
    }
  }

  private static void fetchEuroValue()
  {
    if (dom == null)
      fetchDocument();
    euroToRubleRatio = dom == null ? 0d : extractEuroValue();
  }

  private static double getDoubleValue(final Element ele, final String tagName)
  {
    final NodeList nl = ele.getElementsByTagName(tagName);
    if (nl == null || nl.getLength() <= 0)
      return 0d;
    Double result = 0d;
    final Element el = (Element) nl.item(0);
    final DecimalFormat format = new DecimalFormat();
    try
    {
      result = (Double) format.parse(el.getFirstChild().getNodeValue()
          .toString());
    } catch (final DOMException e)
    {
      e.printStackTrace();
    } catch (final ParseException e)
    {
      e.printStackTrace();
    }
    return result;
  }

  public static Double getEuroToRubleRatio()
  {
    if (euroToRubleRatio < 0)
      fetchEuroValue();
    return euroToRubleRatio;
  }
}
